package com.cdxy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cdxy.dmr.dataObject.*;
import com.cdxy.dmr.repository.*;
import com.cdxy.enums.BizErrorEnum;
import com.cdxy.enums.SaveTypeEnum;
import com.cdxy.model.dto.base.exception.BusinessException;
import com.cdxy.model.dto.base.resp.BasePageResp;
import com.cdxy.model.dto.req.SaveHotelReq;
import com.cdxy.model.dto.req.SaveListReq;
import com.cdxy.model.dto.req.SavePostReq;
import com.cdxy.model.dto.req.SaveSceneReq;
import com.cdxy.model.dto.resp.SaveListResp;
import com.cdxy.model.info.SaveInfo;
import com.cdxy.service.IUserSaveService;
import com.cdxy.util.BeanUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户收藏表 服务实现类
 * </p>
 *
 * @author autoGenCode
 * @since 2020-03-05
 */
@Service
public class UserSaveServiceImpl implements IUserSaveService {

    @Autowired
    private UserSaveRepository userSaveRepository;

    @Autowired
    private AxUserProfileRepository axUserProfileRepository;

    @Autowired
    private ScenePostRepository scenePostRepository;

    @Autowired
    private HotelRepository hotelRepository;

    @Autowired
    private SceneRepository sceneRepository;

    @Override
    public void savePost(SavePostReq savePostReq) {
        Integer postId = savePostReq.getPostId();
        Integer axUid = savePostReq.getAxUid();
        Integer type = savePostReq.getType();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

        UserSaveDO userSaveDO = userSaveRepository.getByBusinessIdAndAxUidAndType(postId, axUid, SaveTypeEnum.POST);
        if (userSaveDO != null && type == 1) {
            throw new BusinessException(BizErrorEnum.SAVE_ERROR, "该帖子已收藏");
        }
        if (userSaveDO == null && type == 2) {
            throw new BusinessException(BizErrorEnum.SAVE_ERROR, "该帖子未收藏");
        }

        if (type == 1) {
            ScenePostDO scenePostDO = scenePostRepository.getById(postId);
            AxUserProfileDO axUserProfileDO = axUserProfileRepository.getById(scenePostDO.getAxUid());
            userSaveDO = new UserSaveDO();
            userSaveDO.setAxUid(axUid);
            userSaveDO.setName(axUserProfileDO.getNickname());
            userSaveDO.setAvatar(axUserProfileDO.getAvatar());
            userSaveDO.setContent(scenePostDO.getContent());
            userSaveDO.setBusinessId(postId);
            userSaveDO.setType(SaveTypeEnum.POST.name());
            userSaveDO.setViewTime(dateTimeFormatter.format(LocalDateTime.now()));
            userSaveRepository.save(userSaveDO);
        } else if (type == 2) {
            userSaveRepository.removeById(userSaveDO.getId());
        }

    }

    @Override
    public void saveHotel(SaveHotelReq saveHotelReq) {
        Integer hotelId = saveHotelReq.getHotelId();
        Integer axUid = saveHotelReq.getAxUid();
        Integer type = saveHotelReq.getType();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

        UserSaveDO userSaveDO = userSaveRepository.getByBusinessIdAndAxUidAndType(hotelId, axUid, SaveTypeEnum.HOTEL);
        if (userSaveDO != null && type == 1) {
            throw new BusinessException(BizErrorEnum.SAVE_ERROR, "该酒店已收藏");
        }
        if (userSaveDO == null && type == 2) {
            throw new BusinessException(BizErrorEnum.SAVE_ERROR, "该酒店未收藏");
        }

        if (type == 1) {
            HotelDO hotelDO = hotelRepository.getById(hotelId);
            userSaveDO = new UserSaveDO();
            userSaveDO.setAxUid(axUid);
            userSaveDO.setName(hotelDO.getName());
            userSaveDO.setAvatar(hotelDO.getImg());
            userSaveDO.setContent(hotelDO.getOverview());
            userSaveDO.setBusinessId(hotelId);
            userSaveDO.setType(SaveTypeEnum.HOTEL.name());
            userSaveDO.setViewTime(dateTimeFormatter.format(LocalDateTime.now()));
            userSaveRepository.save(userSaveDO);
        } else if (type == 2) {
            userSaveRepository.removeById(userSaveDO.getId());
        }
    }

    @Override
    public void saveScene(SaveSceneReq saveSceneReq) {
        Integer sceneId = saveSceneReq.getSceneId();
        Integer axUid = saveSceneReq.getAxUid();
        Integer type = saveSceneReq.getType();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");

        UserSaveDO userSaveDO = userSaveRepository.getByBusinessIdAndAxUidAndType(sceneId, axUid, SaveTypeEnum.SCENE);
        if (userSaveDO != null && type == 1) {
            throw new BusinessException(BizErrorEnum.SAVE_ERROR, "该景点已收藏");
        }
        if (userSaveDO == null && type == 2) {
            throw new BusinessException(BizErrorEnum.SAVE_ERROR, "未收藏过该景点");
        }

        if (type == 1) {
            SceneDO sceneDO = sceneRepository.getById(sceneId);
            userSaveDO = new UserSaveDO();
            userSaveDO.setAxUid(axUid);
            userSaveDO.setName(sceneDO.getName());
            userSaveDO.setAvatar(sceneDO.getSmallImg());
            userSaveDO.setContent(sceneDO.getOverview());
            userSaveDO.setBusinessId(sceneId);
            userSaveDO.setType(SaveTypeEnum.SCENE.name());
            userSaveDO.setViewTime(dateTimeFormatter.format(LocalDateTime.now()));
            userSaveRepository.save(userSaveDO);
        } else if (type == 2) {
            userSaveRepository.removeById(userSaveDO.getId());
        }

    }

    @Override
    public BasePageResp<SaveListResp> saveList(SaveListReq saveListReq) {
        Integer index = saveListReq.getIndex();
        Integer size = saveListReq.getSize();
        Integer type = saveListReq.getType();
        Integer axUid = saveListReq.getAxUid();

        IPage<UserSaveDO> page = new Page<>(index, size);
        LambdaQueryWrapper<UserSaveDO> queryWrapper = (new QueryWrapper<UserSaveDO>()).lambda();
        queryWrapper.eq(UserSaveDO::getAxUid, axUid);
        if (type == 1) {
            queryWrapper.eq(UserSaveDO::getType, SaveTypeEnum.SCENE.name());
        } else if (type == 2) {
            queryWrapper.eq(UserSaveDO::getType, SaveTypeEnum.HOTEL.name());
        } else {
            queryWrapper.eq(UserSaveDO::getType, SaveTypeEnum.POST.name());
        }
        page = userSaveRepository.page(page, queryWrapper);


        BasePageResp<SaveListResp> basePageResp = BeanUtil.copyPropertiesByFastJson(page, BasePageResp.class);
        List<SaveListResp> saveListRespList = BeanUtil.copyPropertiesByFastJson(page.getRecords(), SaveListResp.class);
        basePageResp.setRecords(saveListRespList);

        basePageResp.setLastPage(size * index >= page.getTotal());

        return basePageResp;
    }

    @Override
    public SaveInfo saveStatus(Integer axUid, Integer businessId, SaveTypeEnum typeEnum) {
        if (axUid == null) {
            return new SaveInfo();
        }
        SaveInfo saveInfo = new SaveInfo();
        saveInfo.setBusinessId(businessId);
        UserSaveDO userSaveDO = userSaveRepository.getByBusinessIdAndAxUidAndType(businessId, axUid, typeEnum);
        if (userSaveDO == null) {
            saveInfo.setIsSave(false);
        } else {
            saveInfo.setIsSave(true);
        }
        return saveInfo;
    }

    @Override
    public List<SaveInfo> saveStatusList(List<Integer> businessId, Integer axUid, SaveTypeEnum typeEnum) {
        if (axUid == null) {
            return new ArrayList<>(0);
        }
        List<UserSaveDO> userSaveDOList = userSaveRepository.listByBusinessIdAndAxUidAndType(businessId, axUid, typeEnum);
        List<SaveInfo> saveInfoList = new ArrayList<>(businessId.size());
        Map<Integer, UserSaveDO> map = userSaveDOList.stream().collect(Collectors.toMap(UserSaveDO::getBusinessId, obj -> obj));
        businessId.forEach(integer -> {
            UserSaveDO userSaveDO = map.get(integer);
            SaveInfo saveInfo = new SaveInfo();
            saveInfo.setBusinessId(integer);
            if (userSaveDO == null) {
                saveInfo.setIsSave(false);
            } else {
                saveInfo.setIsSave(true);
            }
            saveInfoList.add(saveInfo);
        });
        return saveInfoList;
    }
}
